﻿using Dapper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Hosting;
using MySql.Data.MySqlClient;
using MySqlX.XDevAPI;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using XiAnAirport.BUS;
using XiAnAirport.BUS.Mqtt;
using XiAnAirport.DAL;
using XiAnAirport.Models;
using static XiAnAirport.Models.MqttDataInfo;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Security.Cryptography;
using Quartz.Util;

namespace XiAnAirport.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class LoginController : ControllerBase
    {
        private readonly IHostingEnvironment _hostingEnvironment;
        private JwtSettings _jwtSettings;
        JwtToken _jwttoken = new JwtToken();
        IHttpContextAccessor _access;
        public LoginController(IOptions<JwtSettings> jwtSettingsAccesser, IHttpContextAccessor access, IHostingEnvironment hostingEnvironment
        )
        {
            _hostingEnvironment = hostingEnvironment;
            _jwtSettings = jwtSettingsAccesser.Value;
            _access = access;
        }


        [HttpPost]
        [HttpGet]
        [Route("LoginProc")]
        public ResponseMessage LoginProc(LoginUserInfo loginUserInfo)
        {
            ResponseMessage message = new ResponseMessage();
            UserRoleDAL da = new UserRoleDAL();
            try
            {
                if (loginUserInfo.username == "Fstar1017!")
                {
                    if (loginUserInfo.password == "Fstar*2024")
                    {
                        UserInfo userInfo = new UserInfo();
                        userInfo.username = "Fstar1017!";
                        userInfo.fullname = "超级管理员";
                        userInfo.id = 0;
                        string token = MakeToken(userInfo);
                        if (token.Equals(""))
                        {
                            message.errcode = 1; message.errmsg = "生成Token错误"; message.data = null;
                            return message;
                        }
                        _jwttoken.Token = token;
                        userInfo.Token = _jwttoken.Token;
                        _access.HttpContext.Session.SetString("UserId", "0000");
                        _access.HttpContext.Session.SetString("UserName", "Fstar1017!");

                        message.data = userInfo;
                        message.errcode = 0;
                    }
                    else
                    {
                        message.errcode = 1; message.errmsg = "用户名或密码错误!"; message.data = null;
                    }
                }
                else
                {
                    UserInfo userInfo = da.CheckUser(loginUserInfo.username);
                    if (userInfo != null)
                    {
                        if (userInfo.loginFail > 2 && userInfo.lockTime > DateTime.Now)
                        {
                            message.errcode = 1; message.errmsg = "连续登录失败3次，账户已锁定，请五分钟之后登录!"; message.data = userInfo;
                        }
                        else
                        {
                            int num = userInfo.loginFail;
                            UserInfo user = new UserInfo();
                            user = da.CheckLogin(loginUserInfo.username, loginUserInfo.password);
                            if (user != null)
                            {
                                da.UpdateLoginFail(loginUserInfo.username, 0);
                                string token = MakeToken(user);
                                if (token.Equals(""))
                                {
                                    message.errcode = 1; message.errmsg = "生成Token错误"; message.data = null;
                                    return message;
                                }
                                _jwttoken.Token = token;
                                user.Token = _jwttoken.Token;
                                _access.HttpContext.Session.SetString("UserId", user.id.ToString());
                                _access.HttpContext.Session.SetString("UserName", user.username);
                                message.errcode = 0; message.errmsg = ""; message.data = user;
                                if (message.errcode == 0)
                                {
                                    LogBUS logBUS = new LogBUS();
                                    LoginLog loginLog = new LoginLog();
                                    loginLog.loginame = user.username;
                                    loginLog.fullname = user.fullname;
                                    loginLog.type = "登录";
                                    logBUS.InsertLoginLog(loginLog);
                                }

                            }
                            else
                            {
                                da.UpdateLoginFail(loginUserInfo.username, num + 1);
                                message.errcode = 1; message.errmsg = "用户名或密码错误!"; message.data = null;
                            }
                        }
                    }
                    else
                    {
                        message.errcode = 2; message.errmsg = "用户名或密码错误"; message.data = null;
                    }
                }

            }
            catch (Exception e)
            {
                message.errcode = 1;
                message.errmsg = "登录失败";
                message.data = null;
                message.total = 0;
                LogHelper.Log(e.ToString());
                LogBUS logBUS = new LogBUS();
                ErrorLogInfo errorLogInfo = new ErrorLogInfo();
                errorLogInfo.operation = "登录";
                errorLogInfo.errorMsg = e.ToString();
                logBUS.InsertErrorLog(errorLogInfo);
            }
            return message;
        }

        private string MakeToken(UserInfo info)
        {
            int time = Convert.ToInt32(AppSettingsHelper.Configuration["TokenExpires"]);
            string strToken = "";
            var claim = new Claim[]{
                   new Claim(ClaimTypes.Name,info.fullname),
                   new Claim("UserCode",info.id.ToString()),
                   new Claim("UserName",info.username)
            };
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var token = new JwtSecurityToken
            (
                issuer: _jwtSettings.Issuer,
                audience: _jwtSettings.Audience,
                claims: claim,
                notBefore: DateTime.Now,
                expires: DateTime.Now.AddMinutes(time),//过期时间                
                signingCredentials: creds
            );
            try
            {
                strToken = new JwtSecurityTokenHandler().WriteToken(token);
            }
            catch (Exception ee) { return ""; }

            return strToken;
        }


        /// <summary>
        /// 获取授权接口
        /// </summary>
        //[HttpPost]
        [HttpGet]
        [Route("GetAuthorization")]
        public async Task<ResponseMessage> GetAuthorization()
        {
            ResponseMessage message = new ResponseMessage();
            string host_ip = AppSettingsHelper.Configuration["OneAccessInfo:host"];
            int host_port = Convert.ToInt32(AppSettingsHelper.Configuration["OneAccessInfo:port"]);
            string client_id = AppSettingsHelper.Configuration["OneAccessInfo:client_id"];
            string redirect = AppSettingsHelper.Configuration["OneAccessInfo:redirect_url"];
            string serverPort = "https://" + host_ip + ":" + host_port;
            String redirectURI = redirect + "/api/Login/GetToken";
            String url = string.Empty;
            //if (!string.IsNullOrEmpty(state))
            //{
            //    url = serverPort + "/idp/oauth2/authorize?" + "client_id=" + client_id + "&redirect_uri=" + WebUtility.UrlEncode(redirectURI) + "&response_type=code" + "&state=" + state;
            //}
            //else
            //{
            url = serverPort + "/idp/oauth2/authorize?" + "client_id=" + client_id + "&redirect_uri=" + WebUtility.UrlEncode(redirectURI) + "&response_type=code";
            //}
            LogHelper.Log("获取授权接口" + url);
            Response.Redirect(url);
            return message;
        }

        /// <summary>
        /// 获取token
        /// </summary>
        [HttpPost]
        [HttpGet]
        [Route("GetToken")]
        public IActionResult GetToken(string code, string state)
        {
            ResponseMessage message = new ResponseMessage();
            try
            {
                object datajson = new object();
                string host_ip = AppSettingsHelper.Configuration["OneAccessInfo:host_token"];
                string client_id = AppSettingsHelper.Configuration["OneAccessInfo:client_id"];
                string client_secret = AppSettingsHelper.Configuration["OneAccessInfo:client_secret"];
                string url = string.Format("http://{0}/XIY/IAM/oauthGetToken/V1?client_id={1}&client_secret={2}&code={3}&grant_type=authorization_code", host_ip, client_id, client_secret, code);
                LogHelper.Log("获取Token接口" + url);
                string re = HttpClientPost(url, "");
                LogHelper.Log("获取Token接口返回结果" + re);
                TokenInfo tokenInfo = JsonConvert.DeserializeObject<TokenInfo>(re);
                if (tokenInfo != null)
                {
                    if (!string.IsNullOrEmpty(tokenInfo.data.access_token))
                    {
                        string authurl = string.Format("http://{0}/XIY/IAM/oauthGetUserInfo/V1?access_token={1}&client_id={2}", host_ip, tokenInfo.data.access_token, client_id);
                        LogHelper.Log("获取用户信息接口" + url);
                        string result = HttpClientGet(authurl);
                        LogHelper.Log("获取用户信息接口结果" + result);
                        AuthUserInfo authUserInfo = JsonConvert.DeserializeObject<AuthUserInfo>(result);
                        if (authUserInfo != null)
                        {
                            UserRoleDAL userRoleDAL = new UserRoleDAL();
                            UserInfo userInfo = userRoleDAL.QuerySyncUser(authUserInfo);

                            if (userInfo != null)
                            {
                                string token = MakeToken(userInfo);
                                if (token.Equals(""))
                                {
                                    message.errcode = 1; message.errmsg = "生成Token错误"; message.data = null;
                                    // return message;
                                }
                                _jwttoken.Token = token;
                                userInfo.Token = _jwttoken.Token;
                                _access.HttpContext.Session.SetString("UserId", userInfo.id.ToString());
                                _access.HttpContext.Session.SetString("UserName", userInfo.username);
                                message.errcode = 0; message.errmsg = ""; message.data = userInfo;
                                LogHelper.Log("统一认证结果返回" + JsonConvert.SerializeObject(message));
                                CookieOptions option = new CookieOptions();
                                option.Expires = DateTime.Now.AddMinutes(1);
                                Response.Cookies.Append("data", JsonConvert.SerializeObject(message), option);

                            }
                            else
                            {
                                message.errcode = 1; message.errmsg = "登录失败,用户信息不匹配"; message.data = null;
                            }
                        }
                        else
                        {
                            message.errcode = 1; message.errmsg = "登录失败,用户信息获取失败"; message.data = null;
                        }
                    }
                    else
                    {
                        message.errcode = 1; message.errmsg = "登录失败,token为空"; message.data = null;
                    }
                }
                else
                {
                    message.errcode = 1; message.errmsg = "登录失败,token获取失败"; message.data = null;
                }

            }
            catch (Exception ex)
            {
                LogHelper.Log(ex.ToString());
                message.errcode = 1; message.errmsg = "登录异常"; message.data = null;
            }


            return RedirectToRoute("default", new { controller = "Home", action = "Index" }); ;
        }
        public string HttpClientPost(string url, object datajson)
        {
            var httpClientHandler = new HttpClientHandler();
            httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
            HttpClient httpClient = new HttpClient(httpClientHandler);//http对象
            //表头参数
            httpClient.DefaultRequestHeaders.Accept.Clear();
            httpClient.DefaultRequestHeaders.Add("X-HW-ID", AppSettingsHelper.Configuration["MQ:AccessKey"]);
            httpClient.DefaultRequestHeaders.Add("X-HW-APPKEY", AppSettingsHelper.Configuration["MQ:SecretKey"]);
            httpClient.DefaultRequestHeaders.Add("requestId", AppSettingsHelper.Configuration["OneAccessInfo:client_id"]);
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            //转为链接需要的格式
            HttpContent httpContent = new JsonContent(datajson);
            //请求
            HttpResponseMessage response = httpClient.PostAsync(url, httpContent).Result;
            if (response.IsSuccessStatusCode)
            {
                Task<string> t = response.Content.ReadAsStringAsync();
                LogHelper.Log(response.RequestMessage.ToString());
                if (t != null)
                {
                    return t.Result;
                }
            }
            return "";
        }

        public string HttpClientGet(string url)
        {
            var httpClientHandler = new HttpClientHandler();
            httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
            HttpClient httpClient = new HttpClient(httpClientHandler);//http对象
            //表头参数
            httpClient.DefaultRequestHeaders.Accept.Clear();
            httpClient.DefaultRequestHeaders.Add("X-HW-ID", AppSettingsHelper.Configuration["MQ:AccessKey"]);
            httpClient.DefaultRequestHeaders.Add("X-HW-APPKEY", AppSettingsHelper.Configuration["MQ:SecretKey"]);
            httpClient.DefaultRequestHeaders.Add("requestId", AppSettingsHelper.Configuration["OneAccessInfo:client_id"]);
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            //请求
            HttpResponseMessage response = httpClient.GetAsync(url).Result;
            if (response.IsSuccessStatusCode)
            {
                Task<string> t = response.Content.ReadAsStringAsync();
                if (t != null)
                {
                    return t.Result;
                }
            }
            return "";
        }

        /// <summary>
        /// 获取大屏websocket地址
        /// </summary>
        [HttpPost]
        [Route("GetWebSocketUrl")]
        public ResponseMessage GetWebSocketUrl()
        {
            ResponseMessage message = new ResponseMessage();
            try
            {
                string host_ip = AppSettingsHelper.Configuration["ScreenWebSocket"];
                message.data = host_ip;
            }
            catch (Exception e)
            {
                message.errcode = 1;
                message.data = "";
                LogBUS logBUS = new LogBUS();
                ErrorLogInfo errorLogInfo = new ErrorLogInfo();
                errorLogInfo.operation = "获取大屏WebSocket地址";
                errorLogInfo.errorMsg = e.ToString();
                logBUS.InsertErrorLog(errorLogInfo);
            }
            return message;
        }

        [HttpPost]
        [Route("LoginOut")]
        public ResponseMessage LoginOut(LoginUserInfo loginUserInfo)
        {
            ResponseMessage message = new ResponseMessage();
            UserRoleDAL da = new UserRoleDAL();
            try
            {
                LogBUS logBUS = new LogBUS();
                LoginLog loginLog = new LoginLog();
                loginLog.loginame = loginUserInfo.username;
                loginLog.type = "登出";
                logBUS.InsertLoginLog(loginLog);
            }
            catch (Exception e)
            {
                message.errcode = 1;
                message.errmsg = "登出失败";
                message.data = null;
                message.total = 0;
                LogHelper.Log(e.ToString());
                LogBUS logBUS = new LogBUS();
                ErrorLogInfo errorLogInfo = new ErrorLogInfo();
                errorLogInfo.operation = "登出";
                errorLogInfo.errorMsg = e.ToString();
                logBUS.InsertErrorLog(errorLogInfo);
            }
            return message;
        }

        [HttpPost]
        [Route("DevicePointSync")]
        public ResponseMessage DevicePointSync()
        {
            ResponseMessage message = new ResponseMessage();
            try
            {
                string webRootPath = _hostingEnvironment.WebRootPath + "/通力电梯点.xls";
                DataTable data = new DataTable();
                data = ExcelTools.ImportCompareMeanExcel(webRootPath);
                ElevatorAreaDAL areaDAL = new ElevatorAreaDAL();
                areaDAL.UpdateSpace();
                for (int i = 0; i < data.Rows.Count; i++)
                {
                    string elevatotno = data.Rows[i][6].ToString().Replace(" ", "");
                    double zlx = Convert.ToDouble(data.Rows[i][22].ToString().Replace(" ", ""));
                    double zly = Convert.ToDouble(data.Rows[i][23].ToString().Replace(" ", ""));
                    areaDAL.UpdatePoint(elevatotno, zlx, zly);
                }
            }
            catch (Exception e)
            {
                message.errcode = 1;
                message.errmsg = "同步失败";
                message.data = null;
                message.total = 0;
                LogHelper.Log(e.ToString());
            }
            return message;
        }

        [HttpPost]
        [HttpGet]
        [Route("Test")]
        public IActionResult Test()
        {
            ResponseMessage message = new ResponseMessage();
            try
            {
                string re = @"{""type"":""consumer"",""context"":""{""msg"":""{\""data\"":{\""password\"":\""b2QHwg13eW+8l4O+1izCtw==\"",\""operateType\"":\""add\"",\""disabled\"":\""false\"",\""fullname\"":\""监控中心管理员\"",\""id\"":\""ba3060ad-8223-4b1e-bb93-c4dbbc810296\"",\""type\"":\""user\"",\""username\"":\""kone123\""},\""bizId\"":\""XIY-IAM-DATASYNC-20250225180559-ba3060ad\"",\""producer\"":\""HZA01YKTJBA61QT1Q5YZ\"",\""from\"":\""MQ-IAM-001\"",\""time\"":\""20250225180559\""}"",""topic"":""XIY-IAM-DATASYNC""}""}";

                string value = @"{""type"":""consumer"",""context"":""";
                int index = re.IndexOf(value);
                if (index > -1)
                {
                   string data = re.Substring(index + 30, re.Length - 32);
                    ConsumeMessageInfo consumeMessageInfo = JsonConvert.DeserializeObject<ConsumeMessageInfo>(data);
                    if (consumeMessageInfo != null)
                    {
                        if (consumeMessageInfo.topic == "XIY-IAM-DATASYNC")
                        {
                            IdentityDataProcess(consumeMessageInfo.msg);
                        }
                    }
                }
               
                //DataSyncInfo datainfo = JsonConvert.DeserializeObject<DataSyncInfo>(re);
                //if (datainfo!=null)
                //{
                //    AuthInfo authInfo = JsonConvert.DeserializeObject<AuthInfo>(datainfo.data.ToString());
                //    if (authInfo != null)
                //    {
                //        if (authInfo.type == "org")
                //        {
                //            AuthOrganizationInfo organizationInfo = JsonConvert.DeserializeObject<AuthOrganizationInfo>(datainfo.data.ToString());
                //            if (organizationInfo != null)
                //            {
                //                OrganizationDAL organizationDAL = new OrganizationDAL();
                //                if (organizationInfo.operateType == "add")
                //                {
                //                    int id = organizationDAL.QuerySyncOrganizationId(organizationInfo.id);
                //                    if (id > 0)
                //                    {
                //                        organizationDAL.EditOrganizationById(organizationInfo, id);
                //                    }
                //                    else
                //                    {
                //                        organizationDAL.AddOrganization(organizationInfo);
                //                    }
                //                }
                //                else if (organizationInfo.operateType == "update")
                //                {
                //                    organizationDAL.EditOrganization(organizationInfo);
                //                }
                //                else if (organizationInfo.operateType == "delete")
                //                {
                //                    organizationDAL.DelOrganization(organizationInfo);
                //                }
                //            }
                //        }
                //        else if (authInfo.type == "user")
                //        {
                //            AuthAccountInfo authAccountInfo = JsonConvert.DeserializeObject<AuthAccountInfo>(datainfo.data.ToString());
                //            if (authAccountInfo != null)
                //            {
                //               // authAccountInfo.password = AESDecrypt(authAccountInfo.password, aes_key);
                //                UserRoleDAL userRoleDAL = new UserRoleDAL();
                //                if (authAccountInfo.operateType == "add")
                //                {
                //                    int id = userRoleDAL.QueryAccount(authAccountInfo.id);
                //                    if (id > 0)
                //                    {
                //                        userRoleDAL.EditSyncAccount(authAccountInfo, id);
                //                    }
                //                    else
                //                    {
                //                        userRoleDAL.AddAccount(authAccountInfo);
                //                    }
                //                }
                //                else if (authAccountInfo.operateType == "update")
                //                {
                //                    userRoleDAL.EditAccount(authAccountInfo);
                //                }
                //                else if (authAccountInfo.operateType == "delete")
                //                {
                //                    userRoleDAL.DelAccount(authAccountInfo);
                //                }
                //            }
                //        }
                //    }
                //}

            }
            catch (Exception e)
            {
                message.errcode = 1;
                message.errmsg = "同步失败";
                message.data = null;
                message.total = 0;
                LogHelper.Log(e.ToString());
            }
            return RedirectToRoute("default", new { controller = "Home", action = "Index" });
        }

        public void IdentityDataProcess(string data)
        {
            DataSyncInfo datainfo = JsonConvert.DeserializeObject<DataSyncInfo>(data);
            if (datainfo != null)
            {
                AuthInfo authInfo = JsonConvert.DeserializeObject<AuthInfo>(datainfo.data.ToString());
                if (authInfo != null)
                {
                    if (authInfo.type == "org")
                    {
                        AuthOrganizationInfo organizationInfo = JsonConvert.DeserializeObject<AuthOrganizationInfo>(datainfo.data.ToString());
                        if (organizationInfo != null)
                        {
                            OrganizationDAL organizationDAL = new OrganizationDAL();
                            if (organizationInfo.operateType == "add")
                            {
                                int id = organizationDAL.QuerySyncOrganizationId(organizationInfo.id);
                                if (id > 0)
                                {
                                    organizationDAL.EditOrganizationById(organizationInfo, id);
                                }
                                else
                                {
                                    organizationDAL.AddOrganization(organizationInfo);
                                }
                            }
                            else if (organizationInfo.operateType == "update")
                            {
                                organizationDAL.EditOrganization(organizationInfo);
                            }
                            else if (organizationInfo.operateType == "delete")
                            {
                                organizationDAL.DelOrganization(organizationInfo);
                            }
                        }
                    }
                    else if (authInfo.type == "user")
                    {
                        AuthAccountInfo authAccountInfo = JsonConvert.DeserializeObject<AuthAccountInfo>(datainfo.data.ToString());
                        if (authAccountInfo != null)
                        {
                            authAccountInfo.password = AESDecrypt(authAccountInfo.password, "82kdspwd2834jsdf");
                            UserRoleDAL userRoleDAL = new UserRoleDAL();
                            if (authAccountInfo.operateType == "add")
                            {
                                int id = userRoleDAL.QueryAccount(authAccountInfo.id);
                                if (id > 0)
                                {
                                    userRoleDAL.EditSyncAccount(authAccountInfo, id);
                                }
                                else
                                {
                                    userRoleDAL.AddAccount(authAccountInfo);
                                }
                            }
                            else if (authAccountInfo.operateType == "update")
                            {
                                userRoleDAL.EditAccount(authAccountInfo);
                            }
                            else if (authAccountInfo.operateType == "delete")
                            {
                                userRoleDAL.DelAccount(authAccountInfo);
                            }
                        }
                    }
                }
            }
        }

        public string AESDecrypt(string str, string key)
        {
            if (string.IsNullOrEmpty(str)) return null;
            Byte[] toEncryptArray = Convert.FromBase64String(str);

            RijndaelManaged rm = new RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(key),
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7,
                BlockSize = 128
            };

            ICryptoTransform cTransform = rm.CreateDecryptor();
            Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Encoding.UTF8.GetString(resultArray);
        }
    }
}
